package userInterface

import server._
import contextManager._
import scala.tools.nsc.Interpreter._
import scala.tools.nsc.interpreter._
import messages._

object CommandInterpreter {
	
	private val version = "0.5"
	private val terminationChar = "\n"
	private var debug = false
	private var shouldQuit = false
	var oldContext = new Context(0,0,0)
	var currentContext = new Context(0,0,0)
	
	
	def main(args: Array[String]): Unit = {
		//println("Thanks for coming")
		println("Advanced Topics in Software Engineering")
		println("Sangiorgio - Triverio")
		println("Ca$h server command interpreter (version " + version + ")")
		println("Type 'help' to get the list of commands")
		println(" ")
		
		/* Initialization and setup */
		Server.start
		Server.setup
		ContextManager.start
		
		/* Interpretation loop - we use pattern matching! */
		var line = ""
		var readTokens = List[String]()
		do {
			/* Read from cli */
			print("> ")
			line = readLine()
			if(debug) println("Read:\t"+ line)
			
			/* Split and show tokens */
			readTokens = line.split(' ').toList
			if(debug) {
				print("Tokens: ")
				var i = 1
				//readTokens.foreach(printf("%s ",_))
				for(token <- readTokens) { 
					printf("[%d]%s  ", i, token);
					i += 1
				}
				println()
			}
			
			/* Verify number of parameters and perform pattern matching */
			if(!readTokens.isEmpty) {
				readTokens match {
						case (List("add", _, _) | List("a", _, _))  => {
											if(debug)
												println("--Add command")
											Server.add(new Content(readTokens(1), readTokens(2)))
									  }
						case (List("delete", _) | List("d", _))  => {
											if(debug) println("--Delete command")
											Server.delete(readTokens.last)
									  }
						case (List("lookup", _) | List("l", _))  => {
											if(debug) println("--Lookup command")
											var content = Server.lookup(readTokens.last)
											printf(content)
											printf("\n")
									  }
						case (List("change-context", _, _, _) | List("cc", _, _, _))  => {
											if(debug) println("--Change context command")
											/* Save old context */
											oldContext = new Context(currentContext.cpuUsage,
																	 currentContext.memoryUsage,
																	 currentContext.networkUsage)
											/* Create and submit new context */
											var v1=0; var v2=0; var v3=0
											if(readTokens(1) == "-") v1 = oldContext.cpuUsage
											else v1 = readTokens(1).toInt
											if(readTokens(2) == "-") v2 = oldContext.memoryUsage
											else v2 = readTokens(2).toInt
											if(readTokens(3) == "-") v3 = oldContext.networkUsage
											else v3 = readTokens(3).toInt
											
											currentContext = new Context(v1,v2,v3)
											if(debug) printf("Context switch [%d,%d,%d] => [%d,%d,%d]\n",
															  oldContext.cpuUsage,
															  oldContext.memoryUsage,
															  oldContext.networkUsage,
															  currentContext.cpuUsage,
															  currentContext.memoryUsage,
															  currentContext.networkUsage)
											
											ContextManager ! currentContext
									  }
						case (List("show-context") | List("sc"))  => {
											if(debug) println("--Show context command")
											
											printf("Current context  [%d,%d,%d]\n",
															  currentContext.cpuUsage,
															  currentContext.memoryUsage,
															  currentContext.networkUsage)
									  }
						case (List("list-content") | List("lc")) => {
											if(debug) println("--List content command")
											Server.listContent
									  }
						case List("debug") => {
											if(debug) {
												println("--Toggle debug command")
												debug = false
												println("Debug is now OFF")
											}
											else {
												debug = true
												println("Debug is now ON")
											}
									  }
						case List("version") => {
											if(debug) println("--Version command")
											println("Version " + version)
									  }
						case (List("help") | List("h"))  => {
											if(debug) println("--Help command")
											println("Cache server commands: add, delete, lookup")
											println("Context manager commands: change-context, show-context")
											println("Other commands: help, version, debug")
											println("Quit commands: quit, exit")
									  }
						case (List("exit") | List("quit") | List("q") | List("e"))  => {
											if(debug) println("--Kill command")
											shouldQuit = true
									  }
						case (List("scala") | List("s"))  => {
											if(debug) println("--Scala interpreter launch")
											break(Nil)
									  }
						case _ => printf("Unknown command or wrong number of parameters\n")
				}
			}
			
		} while (shouldQuit == false)
		
		/* Goodbyes */
		println("")
		println("...Goodbye!")
		
		ContextManager ! Stop
		Server ! Stop
	}

}